package com.wdb.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wdb.domain.ColumnInfo;
import com.wdb.domain.GenConfig;
import com.wdb.domain.TableInfo;
import com.wdb.exception.BadRequestException;
import com.wdb.mapper.ColumnInfoMapper;
import com.wdb.service.GeneratorService;
import com.wdb.util.GenUtil;
import com.wdb.utils.PageResult;
import com.wdb.utils.PageUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * @author: wendaobai@qq.com
 * @date: 2024/9/23 星期一 10:47
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class GeneratorServiceImpl extends ServiceImpl<ColumnInfoMapper, ColumnInfo>
    implements GeneratorService {
  private static final String CONFIG_MESSAGE = "请先配置生成器";
  private final ColumnInfoMapper columnInfoMapper;

  @Override
  public PageResult<TableInfo> getTables(String name, Page<Object> page) {
    return PageUtil.toPage(columnInfoMapper.getTables(name, page));
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public List<ColumnInfo> getColumns(String tableName) {
    List<ColumnInfo> columnInfos = columnInfoMapper.findByTableNameOrderByIdAsc(tableName);
    // columnInfos 不为空
    if (!CollectionUtil.isEmpty(columnInfos)) {
      return columnInfos;
    } else {
      columnInfos = query(tableName);
      saveBatch(columnInfos);
      return columnInfos;
    }
  }

  /**
   * 根据表名查询列信息列表 此方法用于从数据库中获取指定表的列信息，并进行必要的处理 主要用于代码生成过程中理解表结构
   *
   * @param tableName 表名，用于标识需要查询的表
   * @return 返回处理后的列信息列表
   */
  @Override
  public List<ColumnInfo> query(String tableName) {
    // 从数据库中获取指定表的列信息
    List<ColumnInfo> columnInfos = columnInfoMapper.getColumns(tableName);
    // 遍历列信息列表，进行必要的处理
    for (ColumnInfo columnInfo : columnInfos) {
      // 设置列所属的表名
      columnInfo.setTableName(tableName);
      // 如果列是主键并且有额外属性，则设置该列不为空
      // 这是为了在代码生成过程中特别标记这类列
      if (GenUtil.PK.equalsIgnoreCase(columnInfo.getKeyType())
          && GenUtil.EXTRA.equalsIgnoreCase(columnInfo.getExtra())) {
        columnInfo.setNotNull(false);
      }
    }
    // 返回处理后的列信息列表
    return columnInfos;
  }

  /**
   * 同步列信息
   *
   * <p>该方法用于同步两个列表中的列信息它接受两个参数：columns和query columns参数表示当前数据表中的列信息，而query参数表示查询到的列信息
   * 通过比较这两个列表，可以实现数据表列信息的同步或者更新
   *
   * @param columnInfos 当前数据表中的列信息列表每个元素都是一个ColumnInfo对象，包含了列的相关信息
   * @param columnInfoList 查询到的列信息列表，用于与当前数据表中的列信息进行同步每个元素也是一个ColumnInfo对象
   */
  @Override
  public void sync(List<ColumnInfo> columnInfos, List<ColumnInfo> columnInfoList) {
    // todo 没有同步代码逻辑
    log.info("columnInfos--{},columnInfoList--{}", columnInfos, columnInfoList);
  }

  @Override
  public void save(List<ColumnInfo> columnInfos) {
    log.info("xxx--{}",columnInfos);
      saveOrUpdateBatch(columnInfos);
  }

  @Override
  public void generator(GenConfig genConfig, List<ColumnInfo> columns) {
    log.info("sdfasdf--{}--{}",genConfig,columns);
    if (genConfig.getId() == null) {
      throw new BadRequestException(CONFIG_MESSAGE);
    }
    try {
      GenUtil.generatorCode(columns, genConfig);
    } catch (Exception e) {
      log.error(e.getMessage(), e);
      throw new BadRequestException("生成失败，请手动处理已生成的文件");
    }
  }

  @Override
  public ResponseEntity<Object> preview(GenConfig genConfig, List<ColumnInfo> columns) {
    if (genConfig.getId() == null) {
      throw new BadRequestException(CONFIG_MESSAGE);
    }
    List<Map<String, Object>> genList = GenUtil.preview(columns, genConfig);
    return new ResponseEntity<>(genList, HttpStatus.OK);
  }
}
